import datetime
import time

from sqlalchemy import Column, Integer, String, Numeric, Unicode, Float
from sqlalchemy.orm import mapper
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.exc import *

class ModelError(Exception):
   pass

encode = lambda strval: strval.encode('utf-8')

Base = declarative_base()
class PyPackageInfo(Base):
   __tablename__ = u'pypi_info'

   pk = Column(Integer, primary_key = True)
   package = Column(Unicode(100), nullable = False)
   version = Column(String(15), nullable = False)
   lastupdate = Column(Float, nullable = False)

   def __init__(self, Package, Version):
      super(PyPackageInfo, self).__init__()
      if Package:
         self.package = Package
      else:
         raise ModelError, "no package information provided!"

      if Version:
         self.version = Version
      else:
         raise ModelError, "no version information for package provided!"

      self.lastupdate = time.time()

   def __str__(self):
      return str(unicode(self))

   def __repr__(self):
      return repr(str(self))

   def __unicode__(self):
      return encode("%s.%s" %(encode(self.package), encode(self.version)))

   def LastUpdate(self):
      return datetime.date.fromtimestamp(self.lastupdate)

   update = property(fget = lambda self: self.LastUpdate())

class PyDbUpdate(Base):
   __tablename__ = u'pypi_dbupdate'

   pk = Column(Integer, primary_key = True)
   lastupdate = Column(Float, nullable = False)

   def __init__(self, Update = None):
      super(PyDbUpdate, self).__init__()

      if Update:
         self.lastupdate = Update
      else:
         self.lastupdate = time.time()

   def __str__(self):
      return str(unicode(self))

   def __repr__(self):
      return repr(str(self))

   def __unicode__(self):
      return unicode(encode(self.LastUpdate()))

   def LastUpdate(self):
      return datetime.date.fromtimestamp(self.lastupdate)

   update = property(fget = lambda self: self.LastUpdate())

class QueryObject(object):
   def __init__(self, Query, Table):
      super(QueryObject, self).__init__()
      self._err = ModelError()
      self._table = None
      self._query = None

      if Query:
         self._query = Query

      if Table is not None:
         self._table = Table

   @property
   def query(self):
      return self._query

   @property
   def table(self):
      return self._table

   def __str__(self):
      return str(unicode(self))

   def __repr__(self):
      return repr(str(self))

   def __unicode__(self):
      return unicode(encode(str(self.table)))

def create(Engine):
   if Engine:
      try:
         Base.metadata.create_all(Engine)
      except OperationalError, message:
         raise ModelError, message
   else:
      raise ModelError, "no engine defined!"
